import ilog.concert.IloException;
import ilog.concert.IloIntVar;
import ilog.concert.IloLinearNumExpr;
import ilog.concert.IloNumVar;
import ilog.cplex.IloCplex;
public class cplex_2 {
    public static void main(String args[]) throws IloException {
        //两个数据集
        int[][] a = {
                {8, 7, 9, 4, 5},
                {8, 0, 7, 4, 4},
                {4, 3, 3, 8, 7},
                {7, 0, 10, 8, 7},
                {1, 1, 0, 2, 8}
        };
        int[][] b = {
                {3, 5, 8, 10, 9},
                {7, 10, 2, 6, 2},
                {7, 3, 5, 1, 8},
                {1, 6, 7, 1, 2},
                {1, 2, 9, 2, 10}
        };
        IloCplex model = new IloCplex();

        //定义决策变量x，决策变量都
        IloIntVar[][] x = new IloIntVar[5][5];
        //定义两个二维优化变量，决策变量x和y，是两个矩阵
        for(int i=0;i<5;i++){
            for(int j=0;j<5;j++){
                //0表示变量的下限，4表示变量的上限，最后一个是变量的名称，用于在模型中标识该变量，方便后续调试和输出结果
                //如果我想使用浮点类型的上下界的话，就需要使用model.numVar()方法去设置上下界
                x[i][j] = model.intVar(0,1,"x["+i+","+j+"]");//因为这个是下标，只能是整数的上下界，原代码的上限是4，不懂，但是上限为1，求解不变
            }
        }

        //定义决策变量y
        IloIntVar[][] y = new IloIntVar[5][5];
        //定义两个二维优化变量，决策变量x和y，是两个矩阵
        for(int i=0;i<5;i++){
            for(int j=0;j<5;j++){
                //0表示变量的下限，4表示变量的上限，最后一个是变量的名称，用于在模型中标识该变量，方便后续调试和输出结果
                y[i][j] = model.intVar(0,1,"y["+i+","+j+"]");
            }
        }

        //定义目标函数
        //构建线性表达式
        IloLinearNumExpr objExpr = model.linearNumExpr();
        for(int i=0;i<5;i++){
            for(int j=0;j<5;j++){
                objExpr.addTerm(a[i][j],x[i][j]);
                objExpr.addTerm(b[i][j],y[i][j]);
            }
        }
        model.addMinimize(objExpr);

        //定义约束条件
        for(int i=0;i<5;i++){
            for(int j=0;j<5;j++){
                //第一组约束
                model.addEq(x[i][j],y[i][j]);
            }
            //第二组约束
            //不建议使用这个，还是使用循环然后使用addTerm去形成一个线性表达式，再去算
            model.addEq(model.sum(x[i]),1);//表示求出x数组第i行的值之和为1
            model.addEq(model.sum(y[i]),1);//表示求出y数组第i行的值之和为1
        }

        //求解模型
        if(model.solve()){
            System.out.println("最优解为：" + model.getObjValue());
            System.out.println("x矩阵：");
            for (int i = 0; i < 5; i++) {
                for (int j = 0; j < 5; j++) {
                    //System.out.println("x[" + i + "," + j + "]: " + model.getValue(x[i][j]));
                    System.out.print(model.getValue(x[i][j])+" ");
                }
                System.out.println();
            }
            System.out.println("y矩阵");
            for (int i = 0; i < 5; i++) {
                for (int j = 0; j < 5; j++) {
                    //System.out.println("y[" + i + "," + j + "]: " + model.getValue(y[i][j]));
                    System.out.print(model.getValue(y[i][j])+" ");
                }
                System.out.println();
            }
        }

        model.end();

    }
}
